﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using FBroSharp;

namespace FBroBrowserAutomation
{
    public partial class Form1 : Form
    {
        private const string SERVER_ID = "main_server";
        private HttpListener _httpListener = null;
        private CancellationTokenSource _cancellationTokenSource = null;
        private ServerConfiguration _config = null;
        private List<string> _clientConnections = new List<string>();
        private int _requestCount = 0;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 初始化UI
            txtHost.Text = "127.0.0.1";
            txtPort.Text = "7777";
            numMaxConnections.Value = 100;
            txtStaticRoot.Text = Path.Combine(Application.StartupPath, "wwwroot");
            txtDefaultFile.Text = "index.html";
            chkEnableCORS.Checked = true;
            chkEnableWebSocket.Checked = true;

            UpdateStatus("就绪 - 点击\"启动服务器\"开始", Color.Blue);
            UpdateServerInfo();
        }

        private void btnStartServer_Click(object sender, EventArgs e)
        {
            try
            {
                if (_httpListener != null && _httpListener.IsListening)
                {
                    MessageBox.Show("服务器已经在运行中！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                // 获取配置
                string host = txtHost.Text.Trim();
                int port = int.Parse(txtPort.Text.Trim());
                int maxConn = (int)numMaxConnections.Value;
                string staticRoot = txtStaticRoot.Text.Trim();
                string defaultFile = txtDefaultFile.Text.Trim();
                bool enableCORS = chkEnableCORS.Checked;
                bool enableWS = chkEnableWebSocket.Checked;

                // 验证参数
                if (string.IsNullOrEmpty(host))
                {
                    MessageBox.Show("请输入服务器地址！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (port <= 0 || port > 65535)
                {
                    MessageBox.Show("端口号必须在1-65535之间！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                // 创建静态文件目录
                if (!string.IsNullOrEmpty(staticRoot) && !Directory.Exists(staticRoot))
                {
                    Directory.CreateDirectory(staticRoot);
                    
                    // 创建示例HTML文件
                    CreateSampleFiles(staticRoot);
                }

                // 保存配置
                _config = new ServerConfiguration
                {
                    Host = host,
                    Port = port,
                    MaxConnections = maxConn,
                    StaticFileRoot = staticRoot,
                    DefaultFile = defaultFile,
                    EnableCORS = enableCORS,
                    EnableWebSocket = enableWS
                };

                // 创建并启动HTTP监听器
                _httpListener = new HttpListener();
                string prefix = $"http://{host}:{port}/";
                _httpListener.Prefixes.Add(prefix);
                _httpListener.Start();

                // 创建取消令牌
                _cancellationTokenSource = new CancellationTokenSource();

                // 启动请求处理任务
                Task.Run(() => HandleRequestsAsync(_cancellationTokenSource.Token));

                // 更新UI
                btnStartServer.Enabled = false;
                btnStopServer.Enabled = true;
                gbServerConfig.Enabled = false;

                string accessUrl = $"http://{host}:{port}";
                UpdateStatus($"✅ 服务器已启动: {accessUrl}", Color.Green);
                AddLog($"服务器启动成功");
                AddLog($"访问地址: {accessUrl}");
                AddLog($"静态文件目录: {staticRoot}");
                AddLog($"WebSocket: {(enableWS ? "已启用" : "已禁用")}");
                AddLog($"CORS: {(enableCORS ? "已启用" : "已禁用")}");
                AddLog($"最大连接数: {maxConn}");
                AddLog($"提示: 使用 HttpListener 实现HTTP服务器");
                
                UpdateServerInfo();
            }
            catch (HttpListenerException ex)
            {
                MessageBox.Show($"启动服务器失败:\n{ex.Message}\n\n提示：可能需要管理员权限运行程序", 
                    "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                UpdateStatus("❌ 服务器启动失败", Color.Red);
                AddLog($"错误: {ex.Message}");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"启动服务器失败:\n{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                UpdateStatus("❌ 服务器启动失败", Color.Red);
                AddLog($"错误: {ex.Message}");
            }
        }

        private void btnStopServer_Click(object sender, EventArgs e)
        {
            try
            {
                if (_httpListener == null || !_httpListener.IsListening)
                {
                    MessageBox.Show("服务器未运行！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                // 取消异步任务
                _cancellationTokenSource?.Cancel();

                // 停止服务器
                _httpListener.Stop();
                _httpListener.Close();
                _httpListener = null;
                _config = null;
                _clientConnections.Clear();
                _requestCount = 0;

                // 更新UI
                btnStartServer.Enabled = true;
                btnStopServer.Enabled = false;
                gbServerConfig.Enabled = true;

                UpdateStatus("⏹ 服务器已停止", Color.Gray);
                AddLog("服务器已停止");
                UpdateServerInfo();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"停止服务器失败:\n{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                AddLog($"停止失败: {ex.Message}");
            }
        }

        private void btnBrowseFolder_Click(object sender, EventArgs e)
        {
            using (var dialog = new FolderBrowserDialog())
            {
                dialog.Description = "选择静态文件根目录";
                dialog.SelectedPath = txtStaticRoot.Text;

                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    txtStaticRoot.Text = dialog.SelectedPath;
                }
            }
        }

        private void btnClearLog_Click(object sender, EventArgs e)
        {
            txtLog.Clear();
        }

        private void btnOpenBrowser_Click(object sender, EventArgs e)
        {
            if (_httpListener == null || !_httpListener.IsListening)
            {
                MessageBox.Show("请先启动服务器！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            try
            {
                string url = $"http://{_config.Host}:{_config.Port}";
                System.Diagnostics.Process.Start(url);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"打开浏览器失败:\n{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // 异步处理HTTP请求
        private async Task HandleRequestsAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested && _httpListener != null && _httpListener.IsListening)
            {
                try
                {
                    var context = await _httpListener.GetContextAsync();
                    
                    // 不等待，允许并发处理
                    _ = Task.Run(() => ProcessRequestAsync(context, cancellationToken), cancellationToken);
                }
                catch (HttpListenerException)
                {
                    // 监听器已停止
                    break;
                }
                catch (ObjectDisposedException)
                {
                    // 监听器已释放
                    break;
                }
                catch (Exception ex)
                {
                    AddLog($"获取请求失败: {ex.Message}");
                }
            }
        }

        // 处理单个请求
        private async Task ProcessRequestAsync(HttpListenerContext context, CancellationToken cancellationToken)
        {
            HttpListenerRequest request = context.Request;
            HttpListenerResponse response = context.Response;

            try
            {
                string clientIp = request.RemoteEndPoint?.ToString() ?? "Unknown";
                string method = request.HttpMethod;
                string path = request.Url?.AbsolutePath ?? "/";
                
                Interlocked.Increment(ref _requestCount);
                AddLog($"[{_requestCount}] {method} {path} - {clientIp}");

                // 设置CORS头
                if (_config.EnableCORS)
                {
                    response.AddHeader("Access-Control-Allow-Origin", "*");
                    response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
                    response.AddHeader("Access-Control-Allow-Headers", "*");
                }

                // 处理OPTIONS预检请求
                if (method == "OPTIONS")
                {
                    response.StatusCode = 200;
                    response.Close();
                    return;
                }

                // WebSocket升级请求
                if (_config.EnableWebSocket && request.Headers["Upgrade"] == "websocket")
                {
                    await HandleWebSocketRequestAsync(context);
                    return;
                }

                // API路由
                if (path.StartsWith("/api/"))
                {
                    HandleApiRequest(path, method, request, response);
                    return;
                }

                // 静态文件服务
                if (!string.IsNullOrEmpty(_config.StaticFileRoot))
                {
                    await ServeStaticFileAsync(path, response);
                    return;
                }

                // 默认响应
                response.StatusCode = 404;
                response.ContentType = "text/html; charset=utf-8";
                byte[] buffer = Encoding.UTF8.GetBytes("<html><body><h1>404 Not Found</h1></body></html>");
                response.ContentLength64 = buffer.Length;
                await response.OutputStream.WriteAsync(buffer, 0, buffer.Length, cancellationToken);
                response.Close();
            }
            catch (Exception ex)
            {
                AddLog($"处理请求错误: {ex.Message}");
                try
                {
                    response.StatusCode = 500;
                    byte[] buffer = Encoding.UTF8.GetBytes($"Internal Server Error: {ex.Message}");
                    response.ContentLength64 = buffer.Length;
                    await response.OutputStream.WriteAsync(buffer, 0, buffer.Length, cancellationToken);
                    response.Close();
                }
                catch { }
            }
        }

        // 处理WebSocket请求
        private async Task HandleWebSocketRequestAsync(HttpListenerContext context)
        {
            try
            {
                var wsContext = await context.AcceptWebSocketAsync(null);
                string clientId = context.Request.RemoteEndPoint?.ToString() ?? "Unknown";
                
                OnClientConnected(clientId);
                AddLog($"WebSocket连接: {clientId}");

                var webSocket = wsContext.WebSocket;
                var buffer = new byte[4096];

                // 发送欢迎消息
                string welcome = $"{{\"type\":\"welcome\",\"message\":\"连接成功\",\"clientId\":\"{clientId}\"}}";
                var welcomeBytes = Encoding.UTF8.GetBytes(welcome);
                await webSocket.SendAsync(new ArraySegment<byte>(welcomeBytes), 
                    System.Net.WebSockets.WebSocketMessageType.Text, true, CancellationToken.None);

                // 接收消息循环
                while (webSocket.State == System.Net.WebSockets.WebSocketState.Open)
                {
                    var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                    
                    if (result.MessageType == System.Net.WebSockets.WebSocketMessageType.Close)
                    {
                        await webSocket.CloseAsync(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, 
                            "", CancellationToken.None);
                        break;
                    }

                    string message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                    AddLog($"WebSocket消息 [{clientId}]: {message}");

                    // 回显消息
                    string echo = $"{{\"type\":\"echo\",\"original\":\"{message}\",\"timestamp\":\"{DateTime.Now:yyyy-MM-dd HH:mm:ss}\"}}";
                    var echoBytes = Encoding.UTF8.GetBytes(echo);
                    await webSocket.SendAsync(new ArraySegment<byte>(echoBytes), 
                        System.Net.WebSockets.WebSocketMessageType.Text, true, CancellationToken.None);
                }

                OnClientDisconnected(clientId);
                AddLog($"WebSocket断开: {clientId}");
            }
            catch (Exception ex)
            {
                AddLog($"WebSocket错误: {ex.Message}");
            }
        }

        // 处理API请求
        private void HandleApiRequest(string path, string method, HttpListenerRequest request, HttpListenerResponse response)
        {
            response.ContentType = "application/json; charset=utf-8";

            string json = "";

            if (path == "/api/test")
            {
                json = $"{{\"status\":\"success\",\"message\":\"API正常工作\",\"timestamp\":\"{DateTime.Now:yyyy-MM-dd HH:mm:ss}\"}}";
            }
            else if (path == "/api/info")
            {
                json = $"{{\"host\":\"{_config.Host}\",\"port\":{_config.Port}," +
                       $"\"websocket\":{_config.EnableWebSocket.ToString().ToLower()}," +
                       $"\"cors\":{_config.EnableCORS.ToString().ToLower()}," +
                       $"\"requests\":{_requestCount}}}";
            }
            else
            {
                response.StatusCode = 404;
                json = "{\"error\":\"API not found\"}";
            }

            byte[] buffer = Encoding.UTF8.GetBytes(json);
            response.ContentLength64 = buffer.Length;
            response.OutputStream.Write(buffer, 0, buffer.Length);
            response.Close();
        }

        // 提供静态文件
        private async Task ServeStaticFileAsync(string path, HttpListenerResponse response)
        {
            try
            {
                if (path == "/")
                {
                    path = "/" + _config.DefaultFile;
                }

                string filePath = Path.Combine(_config.StaticFileRoot, path.TrimStart('/').Replace('/', Path.DirectorySeparatorChar));

                if (!File.Exists(filePath))
                {
                    response.StatusCode = 404;
                    byte[] buffer = Encoding.UTF8.GetBytes("<html><body><h1>404 File Not Found</h1></body></html>");
                    response.ContentLength64 = buffer.Length;
                    await response.OutputStream.WriteAsync(buffer, 0, buffer.Length);
                    response.Close();
                    return;
                }

                // 设置Content-Type
                string contentType = GetContentType(filePath);
                response.ContentType = contentType;

                // 读取并发送文件
                byte[] fileBytes = await Task.Run(() => File.ReadAllBytes(filePath));
                response.ContentLength64 = fileBytes.Length;
                await response.OutputStream.WriteAsync(fileBytes, 0, fileBytes.Length);
                response.Close();
            }
            catch (Exception ex)
            {
                response.StatusCode = 500;
                byte[] buffer = Encoding.UTF8.GetBytes($"Error serving file: {ex.Message}");
                response.ContentLength64 = buffer.Length;
                await response.OutputStream.WriteAsync(buffer, 0, buffer.Length);
                response.Close();
            }
        }

        // 获取MIME类型
        private string GetContentType(string filePath)
        {
            string extension = Path.GetExtension(filePath).ToLower();
            switch (extension)
            {
                case ".html":
                case ".htm":
                    return "text/html; charset=utf-8";
                case ".css":
                    return "text/css; charset=utf-8";
                case ".js":
                    return "application/javascript; charset=utf-8";
                case ".json":
                    return "application/json; charset=utf-8";
                case ".png":
                    return "image/png";
                case ".jpg":
                case ".jpeg":
                    return "image/jpeg";
                case ".gif":
                    return "image/gif";
                case ".svg":
                    return "image/svg+xml";
                case ".ico":
                    return "image/x-icon";
                case ".txt":
                    return "text/plain; charset=utf-8";
                default:
                    return "application/octet-stream";
            }
        }

        // 公共方法供处理器调用
        public void UpdateStatus(string message, Color color)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => UpdateStatus(message, color)));
                return;
            }

            lblStatus.Text = message;
            lblStatus.ForeColor = color;
        }

        public void AddLog(string message)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => AddLog(message)));
                return;
            }

            string timeStamp = DateTime.Now.ToString("HH:mm:ss");
            txtLog.AppendText($"[{timeStamp}] {message}\r\n");
        }

        public void OnClientConnected(string clientId)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => OnClientConnected(clientId)));
                return;
            }

            _clientConnections.Add(clientId);
            UpdateServerInfo();
            AddLog($"客户端连接: {clientId}");
        }

        public void OnClientDisconnected(string clientId)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => OnClientDisconnected(clientId)));
                return;
            }

            _clientConnections.Remove(clientId);
            UpdateServerInfo();
            AddLog($"客户端断开: {clientId}");
        }

        private void UpdateServerInfo()
        {
            if (_httpListener == null || !_httpListener.IsListening)
            {
                lblServerStatus.Text = "未运行";
                lblServerStatus.ForeColor = Color.Gray;
                lblConnectionCount.Text = "0";
                lblAccessUrl.Text = "-";
            }
            else
            {
                lblServerStatus.Text = "运行中";
                lblServerStatus.ForeColor = Color.Green;
                lblConnectionCount.Text = _clientConnections.Count.ToString();
                lblAccessUrl.Text = $"http://{_config.Host}:{_config.Port}";
            }
        }

        private void CreateSampleFiles(string rootPath)
        {
            try
            {
                // 创建示例 index.html
                string indexPath = Path.Combine(rootPath, "index.html");
                if (!File.Exists(indexPath))
                {
                    string html = @"<!DOCTYPE html>
<html lang='zh-CN'>
<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <title>FBro内置服务器</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { 
            font-family: 'Microsoft YaHei', Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .container {
            background: white;
            border-radius: 20px;
            padding: 40px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
            max-width: 800px;
            width: 90%;
        }
        h1 { 
            color: #667eea; 
            margin-bottom: 20px;
            text-align: center;
        }
        .info-box {
            background: #f8f9fa;
            border-left: 4px solid #667eea;
            padding: 15px;
            margin: 20px 0;
            border-radius: 5px;
        }
        .feature {
            display: flex;
            align-items: center;
            margin: 10px 0;
        }
        .feature::before {
            content: '✓';
            color: #28a745;
            font-weight: bold;
            font-size: 20px;
            margin-right: 10px;
        }
        #status {
            text-align: center;
            margin: 20px 0;
            padding: 15px;
            background: #e7f3ff;
            border-radius: 10px;
        }
        button {
            background: #667eea;
            color: white;
            border: none;
            padding: 12px 30px;
            border-radius: 25px;
            cursor: pointer;
            font-size: 16px;
            margin: 10px 5px;
            transition: all 0.3s;
        }
        button:hover {
            background: #764ba2;
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(0,0,0,0.2);
        }
        .button-group {
            text-align: center;
            margin-top: 30px;
        }
        #wsLog {
            background: #f4f4f4;
            border: 1px solid #ddd;
            padding: 15px;
            max-height: 200px;
            overflow-y: auto;
            font-family: 'Courier New', monospace;
            font-size: 12px;
            margin-top: 20px;
            border-radius: 5px;
        }
    </style>
</head>
<body>
    <div class='container'>
        <h1>🚀 FBro内置HTTP/WebSocket服务器</h1>
        
        <div class='info-box'>
            <h3>服务器特性：</h3>
            <div class='feature'>支持HTTP静态文件服务</div>
            <div class='feature'>支持WebSocket实时通信</div>
            <div class='feature'>支持CORS跨域请求</div>
            <div class='feature'>支持RESTful API</div>
            <div class='feature'>支持多客户端连接</div>
        </div>
        
        <div id='status'>
            <h3>服务器状态：<span style='color: #28a745;'>✓ 运行中</span></h3>
            <p>当前时间：<span id='time'></span></p>
        </div>
        
        <div class='button-group'>
            <button onclick='testAPI()'>测试API</button>
            <button onclick='connectWebSocket()'>连接WebSocket</button>
            <button onclick='sendWebSocketMessage()'>发送消息</button>
        </div>
        
        <div id='wsLog' style='display:none;'>
            <strong>WebSocket日志：</strong><br>
            <div id='logContent'></div>
        </div>
    </div>

    <script>
        let ws = null;
        
        // 更新时间
        setInterval(() => {
            document.getElementById('time').textContent = new Date().toLocaleString('zh-CN');
        }, 1000);
        
        function addLog(message) {
            const logDiv = document.getElementById('wsLog');
            const content = document.getElementById('logContent');
            logDiv.style.display = 'block';
            const time = new Date().toLocaleTimeString();
            content.innerHTML += `[${time}] ${message}<br>`;
            content.scrollTop = content.scrollHeight;
        }
        
        function testAPI() {
            addLog('正在测试API...');
            fetch('/api/test')
                .then(response => response.json())
                .then(data => {
                    addLog('✓ API响应: ' + JSON.stringify(data));
                    alert('API测试成功！\\n' + JSON.stringify(data, null, 2));
                })
                .catch(error => {
                    addLog('✗ API错误: ' + error.message);
                    alert('API测试失败：' + error.message);
                });
        }
        
        function connectWebSocket() {
            if (ws && ws.readyState === WebSocket.OPEN) {
                addLog('⚠ WebSocket已连接');
                alert('WebSocket已经连接！');
                return;
            }
            
            const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
            const wsUrl = protocol + '//' + location.host + '/ws';
            
            addLog('正在连接WebSocket: ' + wsUrl);
            ws = new WebSocket(wsUrl);
            
            ws.onopen = () => {
                addLog('✓ WebSocket已连接');
                alert('WebSocket连接成功！');
            };
            
            ws.onmessage = (event) => {
                addLog('← 收到消息: ' + event.data);
            };
            
            ws.onerror = (error) => {
                addLog('✗ WebSocket错误');
            };
            
            ws.onclose = () => {
                addLog('✗ WebSocket已断开');
            };
        }
        
        function sendWebSocketMessage() {
            if (!ws || ws.readyState !== WebSocket.OPEN) {
                addLog('✗ WebSocket未连接');
                alert('请先连接WebSocket！');
                return;
            }
            
            const message = prompt('请输入要发送的消息：', 'Hello Server!');
            if (message) {
                ws.send(message);
                addLog('→ 发送消息: ' + message);
            }
        }
    </script>
</body>
</html>";
                    File.WriteAllText(indexPath, html, Encoding.UTF8);
                }

                AddLog($"示例文件已创建: {indexPath}");
            }
            catch (Exception ex)
            {
                AddLog($"创建示例文件失败: {ex.Message}");
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_httpListener != null && _httpListener.IsListening)
            {
                try
                {
                    _cancellationTokenSource?.Cancel();
                    _httpListener.Stop();
                    _httpListener.Close();
                }
                catch { }
            }
        }
    }

    // 服务器配置类
    public class ServerConfiguration
    {
        public string Host { get; set; }
        public int Port { get; set; }
        public int MaxConnections { get; set; }
        public string StaticFileRoot { get; set; }
        public string DefaultFile { get; set; }
        public bool EnableCORS { get; set; }
        public bool EnableWebSocket { get; set; }
    }
}
